#include<avr/io.h>
#include<avr/interrupt.h>

#include"spi.h"
#include"cc1100-arch.h"
#include"cc1100.h"


extern void cc1100_interrupt_ISR(void);
ISR(SIG_INTERRUPT1)
{
  cc1100_interrupt_ISR();
}



void cc1100_arch_init(void)
{
  spi_init(); 
  SPI_DISABLE();                /* Unselect radio. */
}


uint8_t spi1_write_single(uint8_t byte) {
    uint8_t ret;
    SPI_TX_BUF = byte;
    WAIT_EORX();
    ret = SPI_RX_BUF;
    return ret;
}

uint8_t spi1_read_single(void) {
    return spi1_write_single(0xDB);
}

uint8_t spi1_write(uint8_t* data, int16_t len) {
    uint8_t ret;
    int16_t i;
    
    for (i=0; i<len; i++) {
        SPI_TX_BUF = data[i];
        WAIT_EORX();
        ret = SPI_RX_BUF;
    }
    return ret;
}
void spi1_read(uint8_t* data, int16_t len) {
    int16_t i;
    
    for (i=0; i<len; i++) {
        SPI_TX_BUF = 0xDB;
        WAIT_EORX();
        data[i] = SPI_RX_BUF;
    }
}




uint8_t cc1100_spi_access(uint8_t addr, uint8_t value)
{
  uint8_t ret;

  SPI_DISABLE();
  SPI_ENABLE();

  /* send register address byte, the read/write bit is already configured */
  SPI_TX_BUF = addr;
  WAIT_EOTX();

  SPI_TX_BUF = value;
  WAIT_EOTX();

  ret = SPI_RX_BUF;

  SPI_DISABLE();

  return(ret);
}

uint8_t cc1100_read_reg(uint8_t addr)
{
  return cc1100_spi_access((addr | CC1100_ACCESS_READ), 0xDB);
}

uint8_t cc1100_read_status(uint8_t addr)
{
  return cc1100_spi_access( (addr | CC1100_ACCESS_STATUS), 0xDB );
}


void cc1100_write_reg(uint8_t addr, uint8_t value)
{
  cc1100_spi_access((addr | CC1100_ACCESS_WRITE), value);
}

uint8_t cc1100_strobe_cmd(uint8_t cmd)
{
  uint8_t ret;
  SPI_DISABLE();
  SPI_ENABLE();
  ret = spi1_write_single(cmd | CC1100_ACCESS_STROBE);
  SPI_DISABLE();
  return ret;
}

void cc1100_fifo_put(uint8_t* hdrbuf, uint8_t* buffer, uint16_t applength)
{
  //spi1_select(SPI1_CC1100);
  SPI_DISABLE();
  SPI_ENABLE();
  spi1_write_single(CC1100_DATA_FIFO_ADDR | CC1100_ACCESS_WRITE_BURST);
  spi1_write(hdrbuf, CC1100_HDR_LENGTH);
  spi1_write(buffer, applength);
  //spi1_deselect(SPI1_CC1100);
  SPI_DISABLE();
}

void cc1100_fifo_get(uint8_t* buffer, uint16_t length)
{
  //spi1_select(SPI1_CC1100);
  SPI_DISABLE();
  SPI_ENABLE();
  spi1_write_single(CC1100_DATA_FIFO_ADDR | CC1100_ACCESS_READ_BURST);
  spi1_read(buffer, length);
  //spi1_deselect(SPI1_CC1100);
  SPI_DISABLE();
}






